<?php
/**
 * SEPosition
 *
 * @author Pavel Kovalyov
 *
 */
class RCMS_Object_SEPosition_SEPosition {
    /**
     * @var sting Keyword for search
     */
    protected $_keyword;
    /**
     * @var string Hostname to look for
     */
    protected $_host;
    /**
     * @var int Position in search results
     */
    protected $_position = 999;
    /**
     * @var <array> for future use
     */
    protected $_positionsDump;

    protected $_pageUrl;
    /**
     * @var string Source code of search page results
     */
    protected $_source;
    /**
     * @var string SE Url address
     */
    protected $_seUrl = "";
    /**
     * @var string Url with all necessary parameters
     */
    protected $_query;
    /**
     * @var array Dump of positions in SE results pages
     */
    protected $_dump;
    /**
     * @var string useragent string for curl options
     */
    private  $_userAgent  = "Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7 GTB6";
    /**
     * @var string encoding type for curl options
     */
    private  $_encoding    = "gzip,deflate";

    private $_model = null;

    /**
     * Constructor
     * @access public
     * @param <integer> $keyword
     */
    public function  __construct($pageUrl = "", $keyword = "") {
        $this->_model = new RCMS_Object_SEPosition_SEPositionModel();
        // remove 'http://www.seotoaster.com/'; and uncomment for production
        $hostname = unserialize(Zend_Registry::get('config'))->website->website->url;
        preg_match('/http:\/\/(www\.)?([^$\/]+)\//i',$hostname,$host);
        $this->_host = $host[2];
        $this->_keyword = urlencode($keyword);
        $this->_pageUrl = $pageUrl;
        $this->_positionsDump = $this->_model->getPositions($this->_pageUrl);
    }

    /**
     * Run method checks for existed record in DB
     * and if not or older than two weeks runs the position check again.
     * Returns array with search posiotion history
     *
     * @access public
     * @return <array>
     */
    public function run(){

        $lastPosition = array_pop($this->_positionsDump);
        
        //check if there's no data in db
        if (empty($lastPosition)) {
            $googlePos = $this->_checkGoogle();
            $yahooPos  = $this->_checkYahoo();
            $this->_model->insertPosition($this->_pageUrl, $this->_keyword, $googlePos, $yahooPos);
            //return true;
        } else {
            //check if the record in db older than 2 weeks
            $now    = time();
            $last   = strtotime($lastPosition['date']);
            $elapsed   = time() - strtotime($lastPosition['date']);
            //use 1209600 = two weeks
            if ($elapsed > 1209600){
                $googlePos = $this->_checkGoogle();
                $yahooPos  = $this->_checkYahoo();
                $this->_model->insertPosition($this->_pageUrl, $this->_keyword, $googlePos, $yahooPos);
                //return true;
            }
            //remove next string for production
            //return $elapsed;
        }
        
        return $this->_model->getPositions($this->_pageUrl);
    }

    /**
     * Main method to get page source using curl
     *
     * @access private
     * @return <string> native page content
     */
    private function _getPage(){
        $retData = '';

        if ( $curl = curl_init() ) {
            
            /*
             * setting curl options
             */
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
            curl_setopt($curl, CURLOPT_ENCODING, $this->_encoding);
            curl_setopt($curl, CURLOPT_USERAGENT, $this->_userAgent);
            curl_setopt($curl, CURLOPT_HEADER, false);
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($curl, CURLOPT_TIMEOUT, 120);
            curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
            curl_setopt($curl,CURLOPT_URL,$this->_query);

            $retData = curl_exec($curl);
            curl_close($curl);
       }

       return $retData;
    }

    /**
     * Check posiotion in Google Search
     * (parsing first 100 search results)
     *
     * @access private
     * @return <integer> 0 - if position is over 100
     */
    private function _checkGoogle()
    {
        $return = false;

        $this->_seUrl = "http://www.google.com/search?hl=en&sa=N&q=";
        $currentPosition = 0;
        $finalPosition = $this->_position;
        unset($this->_dump);

        for($i=0;$i<100;$i+=10) {

            $this->_query = $this->_seUrl . $this->_keyword . "&start=".(int)$i;
            $this->_source = $this->_getPage();
            //echo $this->_query;
            if( preg_match_all('/<h3 class="?r"?><a href="([^"]+)"/',$this->_source,$results,PREG_SET_ORDER) ){
                
                foreach ($results as $result){
                    $currentPosition++;
                    //var_dump($result);
                    if (preg_match('/^http:\/\/(www\.)?([^$\/]+)\/?/i',$result[1],$host)){
                        

                        if ($host[2] == $this->_host){
                            if ($currentPosition < $finalPosition) $finalPosition=$currentPosition;
                            $return = true;
                        }
                        //$this->_dump[$currentPosition] = $host[2]; //uncoment to dump search results
                    }
                }
            }
        }
        if ($return) return (int)$finalPosition;
        else return (int)0;
    }

    /**
     * Check posiotion in Yahoo!Search
     * (parsing first 100 search results)
     *
     * @access private
     * @return <integer> 0 - if position is over 100
     */
    private function _checkYahoo()
    {
        $return = false;
        $this->_seUrl = "http://search.yahoo.com/search?p=";
        $currentPosition = 0;
        $finalPosition = $this->_position;
        
        unset($this->_dump);
        
        for($i=1;$i<100;$i+=10) {
            $this->_query = $this->_seUrl . $this->_keyword ."&ei=UTF-8&fr=yfp-t-701&xargs=0&pstart=1&b=".$i;
            $this->_source = $this->_getPage();

            if (preg_match_all('/<a class="yschttl spt"([^>]+)/',$this->_source,$results)){
                //echo $this->_query;
                
                foreach ($results[1] as $result) {
                    $currentPosition++;
                    //var_dump($result);
                    if (preg_match_all('/http%3a\/\/(www\.)?([^\/]+)\/?/',$result,$host)){
                        //var_dump($host[2][0]);
                        if ($host[2][0] == $this->_host){
                            if ($currentPosition < $finalPosition) $finalPosition=$currentPosition;
                            $return = true;
                        }
                        //$this->_dump[$currentPosition] = $host[2][0]; //uncoment to dump search results
                    }

                }
            }

        }
        if ($return) return (int)$finalPosition;
        else return (int)0;
    }

    /**
     * Method returns the url to Google Chart API with all necessary parameters to draw position statistic chart.
     * @access public
     * @return string Url of Google Chart
     */
    public function showStatistic($pageUrl)
    {
        
        $positions  = $this->_model->getPositions($pageUrl);
        
        $chart = array (
            'chtt'  => $pageUrl,
            'chts'  => "0000AA,18",
            'cht'   => "bvg",
            'chxt'  => "x,y,y",
            'chs'   => "900x250",
            'chbh'  => "r,0.1,0.5",
            //'chd'   => 's:cEj9U',
            //'chxp'  => '0,0',
            'chd'   => array (
                'start'  => "t:",
                'google' => array (),
                'yahoo'  => array ()
            ),
            'chxl'  => array (
                "2:",
                "low",
                "top",
                "1:",
                "100",
                "0",
                "0:",
            ),
            'chdl'  => array (
                "Google",
                "Yahoo",
            ),
            'chco'  => "FF0000,0000FF",
            'chg'   => '10',
            //'chm'   => 'N,112233,-1,,10|N,112233,0,-1,10',
            'chxr'  => "1,100,0,10",
        );

        $return = "http://chart.apis.google.com/chart?";
        
        foreach ($positions as $value){
            $i++;
            array_push($chart['chd']['google'], ($value['google_pos'] != '0' ? 100 - $value['google_pos'] : 0.25));
            array_push($chart['chd']['yahoo'], ($value['yahoo_pos'] != '0' ? 100 - $value['yahoo_pos'] : 0.25));
            array_push($chart['chxl'], date("M jS",strtotime($value['date'])));
        }

        foreach ($chart as $key=>$value){
            if (!is_array($value)){
                $tmp[] = $key."=".$value;
            }else{
                foreach ($value as $k => &$v) {
                    if (is_array($v)){
                        $v = implode(",",$v);
                    }
                }
                $tmp[] = $key . "=" . implode("|",$value);
            }
        }
        return str_replace("t:|","t:",$return.implode("&",$tmp));
    }
}